// /////////////////////////////////////////////////////////////////////////////
//
// Name:            asSerializable.cpp
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Binds the Serializable class to AngelScript
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

// Include files
#include "asSerializable.h"

#ifdef __COMPILE_WITH_ANGELSCRIPT__

#include "../../core/GameManager.h"

// ScriptedSerializable class
// ScriptedSerializable constructor
ScriptedSerializable::ScriptedSerializable(asIScriptObject *object)
: mObject(object)
{
    // Set up pointers which will be used.
    mObject->AddRef();
    mContext = GameManager::Instance()->getScriptManager()->getEngine()->CreateContext();
}

// ScriptedSerializable deconstructor
ScriptedSerializable::~ScriptedSerializable()
{
    mContext->Release();
    mObject->Release();
}

// Serializes this object.
bool ScriptedSerializable::onSerialization(SerializedAttributes *attributes)
{
    int id = mObject->GetObjectType()->GetMethodIdByDecl("bool onSerialization(SerializedAttributes @attributes)");

    mContext->Prepare(id);
    mContext->SetObject(mObject);
    mContext->SetArgObject(0, (void*)attributes);
    mContext->Execute();

    return mContext->GetReturnByte();
}

// Deserializes this object.
bool ScriptedSerializable::onDeserialization(SerializedAttributes *attributes)
{
    int id = mObject->GetObjectType()->GetMethodIdByDecl("bool onDeserialization(SerializedAttributes @attributes)");

    mContext->Prepare(id);
    mContext->SetObject(mObject);
    mContext->SetArgObject(0, (void*)attributes);
    mContext->Execute();

    return mContext->GetReturnByte();
}

//! Loads data in the given instance of the Serializable class from an XML file.
bool serializableLoadXML(asIScriptObject *object, const std::string &fileName)
{
    ScriptedSerializable *serializable = new ScriptedSerializable(object);
    bool succeeded = serializable->loadXML(fileName);
    serializable->drop();

    return succeeded;
}

//! Saves data from the given instance of the Serializable class to an XML file.
bool serializableSaveXML(asIScriptObject *object, const std::string &fileName)
{
    ScriptedSerializable *serializable = new ScriptedSerializable(object);
    bool succeeded = serializable->saveXML(fileName);
    serializable->drop();

    return succeeded;
}


//! Binds the Serializable class to AngelScript.
void bindSerializable(asIScriptEngine *engine)
{
    // Forward declarations.
    int r;

    // Bind Serializable class (and dependencies).
    r = engine->RegisterObjectType("Serializable", sizeof(Serializable), asOBJ_REF);
    r = engine->RegisterObjectType("SerializedAttributes", sizeof(SerializedAttributes), asOBJ_REF);


    // Get Serializable base functions.
    bindSerializableBase<EntityComponent>(engine, "Serializable");

    // Define the interface for inheritance.
    r = engine->RegisterInterface("ISerializable");

    r = engine->RegisterInterfaceMethod("ISerializable", "bool onSerialization(SerializedAttributes @attributes)"); assert(r >= 0);
    r = engine->RegisterInterfaceMethod("ISerializable", "bool onDeserialization(SerializedAttributes @attributes)"); assert(r >= 0);

    // Functions for interacting with the ISerializable interface.
    r = engine->RegisterGlobalFunction("bool loadXML(ISerializable@+, const string &in)", asFUNCTION(serializableLoadXML), asCALL_CDECL); assert(r >= 0);
    r = engine->RegisterGlobalFunction("bool saveXML(ISerializable@+, const string &in)", asFUNCTION(serializableSaveXML), asCALL_CDECL); assert(r >= 0);
}

#endif // __COMPILE_WITH_ANGELSCRIPT__

// End of File
